package com.sanctity.utils;

import com.sanctity.constant.RabbitConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

/***
 * @belongsProject spring-cloud
 * @description <TODO description class purpose>
 * @author Sanct
 * @version 1.0.0
 * @create 2024/1/25 14:15
 **/
@Slf4j
@Component("messageProvider")
public class MessageProvider implements RabbitTemplate.ConfirmCallback {

    @Resource(name = "docRabbitTemplate")
    protected RabbitTemplate rabbitTemplate;
    private final CountDownLatch latch;
    public MessageProvider(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
//        this.rabbitTemplate.setMandatory(true);
        this.rabbitTemplate.setConfirmCallback(this);

        latch = new CountDownLatch(1);

//        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
//            @Override
//            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//                if (ack){
//                    log.debug("Message confirmed: " + correlationData.getId());
//                    latch.countDown(); // 标记确认回调执行完成
//                }else{
//                    log.debug("Message not confirmed: " + correlationData.getId() + " - " + cause);
//                    // 在 handleNack 中进行消息重发等处理
//                }
//            }
//        });
    }

    public void sendMessage(String message) throws MQSendException {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        try {
            rabbitTemplate.convertAndSend(RabbitConstants.DIRECT_EXCHANGE,RabbitConstants.MESSAGE_ROUTING_KEY,message,correlationData);
            // 等待交换机确认回调执行完成
            log.debug("Message send to consumer " +  message);
        } catch (AmqpException e) {
            log.debug("Message send failed, correlationData: " + correlationData.getId());
            // 在 convertAndSend 方法中发生异常时，也需要进行消息重发等处理
            throw new MQSendException("Message send failed: " + correlationData.getId(),e);
        }
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack){
            log.debug("Message confirmed: " + correlationData.getId());
            latch.countDown(); // 标记确认回调执行完成
        }else{
            log.debug("Message not confirmed: " + correlationData.getId() + " - " + cause);
            // 在 handleNack 中进行消息重发等处理
        }
    }

    public static class MQSendException extends Exception{
        public MQSendException(String message , Throwable cause){
            super(message,cause);
        }
    }

}
